package com.application.race.manage.player;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import com.application.actor.pojo.Actor;
import com.application.item.manage.ItemManage;
import com.application.item.pojo.ActorHoldItem;
import com.application.item.pojo.Car;
import com.application.item.pojo.Item;
import com.application.item.pojo.Part;
import com.application.race.manage.MapInfo;
import com.application.race.manage.RaceResult;
import com.application.race.manage.action.Action;
import com.application.race.manage.player.effect.Effect;
public class Player {
	public Object[] sendInfo=new Object[7];
    public ArrayList<Integer> partList;
	public ArrayList skills;
	
	public byte ready=0;
	public int _angle=0;
    public double _x,_y,_vx,_vy,_speed,up_speed,down_speed,_braCft,_accCft;
    public double _dvx,_dvy;
    public boolean _up,_down,_left,_right,_brake,_relaseAccelerator,_brake_down,_brake_up;
    public double weight=1200;
    public String _userName;
    public boolean _positionChanged=false;
    public String strsendInfo;
    public int directionArraw;
	static int angle360=360;
	public static double totalLostCft;
	SideClipContrl sideClipContrl;
	ConflictChecker confChk;
    public CarInfo carInfo;
    MapInfo mapInfo;
    public boolean hasAction=false;
    public int actionCode=0;
    public Map crashTable=new HashMap();
    public int actionId=0;
    public int max_blood=1500;
    public int now_blood=1500;
    public int dec_blood=0;
    public boolean dead=false;
    public int totalDamage=0;
    public int bonus=0;
    public int exp=0;
    public int awardItemType=0;
    public int awardItemQtt=0;
    public int awardPartType=0;

    public double racePoint=0;
    public int totalKills=0;
	public double currentSystemTime;
    public int heal=0;
    public boolean hadCrash=false;
    public boolean onCarotic=false;
    public int crashPart;
    public byte teamId=0;
    public Vector<Effect> effects=new Vector<Effect>();
    
    public double controlCft =0.55;
    public Action action;
    public int effectId=0;
    public int site=0;
    public Actor actor;
    public Player(String name,int site,MapInfo mapInfo){
      this._userName=name;
      this.result.uid=name;
      this.result.castItems=this.castItems;
      this.site=site;
      if(site>3) this._angle=180;
      this._x=mapInfo.sitex[site];
      this._y=mapInfo.sitey[site];

      this.mapInfo=mapInfo;
      controlCft*=this.mapInfo.firctCft; 
      //System.out.println(this.mapInfo.firctCft+"  fdfsd");
      sideClipContrl = new SideClipContrl(this);
      action = new Action(this);

    }
    public int carId;
    public void setCar(Car car,ArrayList partList,List<Part> parts){
    	  this.carId=car.itemId;
    	   this.partList=partList;
    	  carInfo=new CarInfo(car,parts);
          _braCft=mapInfo.firctCft*carInfo.braCft*carInfo.slipResistance*controlCft;
          System.out.println(_braCft+"  _braCft");
          _accCft=carInfo.accCft*carInfo.slipResistance*controlCft;
          weight=carInfo.weight;
          max_blood=carInfo.endure;
          now_blood=carInfo.endure;
          confChk =new ConflictChecker(this);
    }
 
    
    boolean move=false;
    public  void nextStatus(){
    	currentSystemTime=System.currentTimeMillis();
    	move=false;
    	this.cacuRuntime();

		if(move){

			//if(this._userName.equals("cuijian"))

			checkPosition();
		}
		
    }

   
    //static final 
    static final int int1=1;
    double temp,temp1;
    public void checkPosition(){

    	temp=_x-carInfo.confRadius;
    	if(temp<mapInfo.map_x)_x=mapInfo.map_x+carInfo.confRadius;
    	temp=_y-carInfo.confRadius;
    	if(temp<mapInfo.map_y)_y=mapInfo.map_y+carInfo.confRadius;
    	temp=_x+carInfo.confRadius;
    	temp1=mapInfo.map_width-int1;
    	if(temp>temp1)_x=mapInfo.map_width-carInfo.confRadius-int1;
    	temp=_y+carInfo.confRadius;
    	temp1=mapInfo.map_height-int1;
    	if(temp>temp1)_y=mapInfo.map_height-carInfo.confRadius-int1;
    }
    
    public void userActionAction(int angle,int acode){
    	if(dead)return;
    	
    	this.hasAction=true;
    	this._angle=angle;
    	action.parseActionCode(acode);
    	resetRunParam();
    }
    public void userActionMove(int angle,double x,double y,
    		int sideClipAngle,double sideClipSpeed,double up_speed,double down_speed,
    		int actionId,int acode){
    	    if(dead)return;
    		this.hasAction=true;
    	    this._angle=angle;
    		this._x=x;
    		this._y=y;
    		this.sideClipContrl.sideClipAngle=sideClipAngle;
    		this.sideClipContrl.speed=sideClipSpeed;
    		if(this.sideClipContrl.speed>int0){
    			sideClipContrl.hasSideClip=true;
    		}
    		this.up_speed=up_speed;
     		this.down_speed=down_speed;
    		action.parseActionCode(acode);
    		resetRunParam();
     		
    }
    public void userAction(int angle,int actionId,int acode){
    	    if(dead)return;
    		this.hasAction=true;
    	    this._angle=angle;
    		action.parseActionCode(acode);
    		resetRunParam();
    }
	public ArrayList<ActorHoldItem> castItems=new ArrayList();
	public void addRaceItem(int itemType){
	
	    boolean exist = false;
		for(int i = 0;i<castItems.size();i++){
			ActorHoldItem item = castItems.get(i);
			if(item.item.itemId == itemType){
				item.num++;
				exist = true;
				break;
			}
		}
		
		if(!exist){
			ActorHoldItem hold=new ActorHoldItem();
			Item item = ItemManage.getItem(itemType, "addRaceItem");
			hold.item=item;
 
			hold.num=1;
			castItems.add(hold);
		}
	}
	public RaceResult result=new RaceResult();
    public void resetRunParam(){
	    turnCoupling=0;
	    moveActionStartTime=System.currentTimeMillis();
	    turnActionStartTime=moveActionStartTime;
    }
	double moveRuntime=0;
    double stopRuntime=0;
    double turnRuntime=0;
    double speed_in_turn;
    double turnCoupling=0;
    double runCoupling=0;
    double mod=0;
    public void resetAction(){
    	this.actionCode=0;
    	this.action.parseActionCode(actionCode);
    }
    static final int int15=15;
    static final int int360=360;
    static final int int0=0;
    static final int int2=2;
	public void cacuRuntime(){
	    
		if(_left||_right){
	        turnRuntime=currentSystemTime-turnActionStartTime;
	        moveRuntime=currentSystemTime-moveActionStartTime;
	        turnActionStartTime=currentSystemTime;
	        moveActionStartTime=currentSystemTime;
	        runCoupling=turnCoupling;
			turnCoupling+=carInfo.turnCft*turnRuntime;
			if(turnCoupling>=int15){
				 moveRuntime=(int15-runCoupling)/carInfo.turnCft;
				 move();
	             turn();
	             turnCoupling-=int15;
				 while(turnCoupling>int15){
					moveRuntime=int15/carInfo.turnCft;
					move();	
			     	turn();
	            	turnCoupling-=int15;
				 }	
			 	 moveRuntime=turnCoupling/carInfo.turnCft;
			 	 move();
				 
			}else{
	             move();
			}
		}else{
	    	moveRuntime=currentSystemTime-moveActionStartTime;
	   		moveActionStartTime=currentSystemTime;
	   		move();
		}
		
	}   
	public void turn(){

    	if(_up||_down){
 			if(_up){
 				sideClipContrl.setSideClipData(controlCft,up_speed,_angle);
 			}else{
 				sideClipContrl.setSideClipData(controlCft,down_speed,_angle);
 			} 
     		if(_up){
 				if(_left)
 					_angle=_angle-int15; 
 				if(_right) 
 					_angle=_angle+int15; 
     		}else{
 				if(_left)
 					_angle=_angle+int15; 
 				if(_right) 
 					_angle=_angle-int15; 
     		}
     	}else{
 			if(_left)
 				_angle=_angle-int15; 
 			if(_right) 
 				_angle=_angle+int15; 
     	}
 		if(_angle>=int360){
 			_angle=_angle%int360;
 		}
 		if(_angle<int0){
 			_angle=_angle+int360;
 		}
	 
	}
	public void move(){
		if(_up){
			move=true;
			moveUp();
		}else if(_down){
			move=true;
			moveDown();
		}else{
			if(sideClipContrl.hasSideClip){
				move=true;
				moveBySideClip();
			}
		}
	}
    double startTime=0,nowTime=0;
    double t0,t1,t2,V=0,V0,V1,a,startV,endV;
        public double turnActionStartTime=0;
        public double moveActionStartTime=0;
        public double stopActionStartTime=0;
        public double go(double speed){
			    //V0=(t0*a+t1*a)/2;  V1=max
		    	//V=(V0*(t1-t0)+V1*(t2-t1))/(t2-t0)
		    V=speed;
		    if(_up)
		    	V1=carInfo.maxUpSpeed;
		    else
		    	V1=carInfo.maxDownSpeed;
		    if(V<V1){
		    	a= _accCft;
		    	startTime=V/a;
		    	nowTime=moveRuntime+startTime;
		    	t0=	startTime;
		    	t2= nowTime;
				startV=t0*a;
				endV=t2*a;
				if(endV>V1){
					t1=V1/a;
					endV=t1*a;
					V0=(startV+endV)/int2;
					V=(V0*(t1-t0)+V1*(t2-t1))/(t2-t0);
				}else{
					V=(startV+endV)/int2;
				}
		       if(_up){
			    	up_speed=endV;
			    	if(up_speed>=carInfo.maxUpSpeed){
			    		up_speed=carInfo.maxUpSpeed;
			    		V=up_speed;
			    	}
		       }
			   else{
			    	down_speed=endV;
				    if(down_speed>=carInfo.maxDownSpeed){
			    		down_speed=carInfo.maxDownSpeed;
			    		V=down_speed;
			    	}
			   }
		    }	
		    return V;
        }

		public double brake(double speed){
		    V=speed;
		    V1=0;
		    if(V>V1){
		    	a= _braCft;
		    	startTime=V/a;
		    	nowTime=startTime-moveRuntime;
		    	t0=	startTime;
		    	t2= nowTime;
				startV=t0*a;
				endV=t2*a;
				if(endV<int0){
					t1=int0;
					endV=int0;
					V0=(startV+endV)/int2;
					V=V0*(t0-t1)/(t0-t2);

				}else{
					V=(startV+endV)/int2;
				}
		       if(_up)
			    	up_speed=endV;
			    else
			    	down_speed=endV;
		    }else{
	    	    if(_up)
			    	up_speed=int0;
			    else
			    	down_speed=int0;
		    	return V1;
		    }
		    return V;	
		}
		static int i4=4;
		public double relaseAccelerator(double speed){
		    V=speed;
		    V1=0;
		    if(V>V1){
		    	a= _braCft/i4;
		    	startTime=V/a;
		    	nowTime=startTime-moveRuntime;
		    	t0=	startTime;
		    	t2= nowTime;
				startV=t0*a;
				endV=t2*a;
				if(endV<int0){
					t1=int0;
					endV=int0;
					V0=(startV+endV)/int2;
					V=V0*(t0-t1)/(t0-t2);
				}else{
					V=(startV+endV)/int2;
				}
		        if(_up)
			    	up_speed=endV;
			    else
			    	down_speed=endV;
		    }else{
	    	    if(_up)
			    	up_speed=int0;
			    else
			    	down_speed=int0;
		    	return V1;
		    }
		    return V;
		}
		double x_off;
		double y_off;
		public  void moveUp(){
			if(_brake_down){
				if(up_speed<=int0){
					_speed=int0;
					_up=false;
					_brake_down=false;
					_down=true;
				}else{
					_speed=brake(up_speed);
				}
			}
			else if(_brake){
				if(up_speed<=int0){
					_speed=int0;
				}else{
					_speed=brake(up_speed);	
				}
			}
			else if(_relaseAccelerator){
				if(up_speed<=int0){
					_up=false;
					_speed=int0;
				}else{
					_speed=relaseAccelerator(up_speed);
				}
			}else
			if(_up){
				if(up_speed<carInfo.maxUpSpeed){
					_speed=go(up_speed);
				}else{
					_speed=up_speed;
				}
			}
			sideClipContrl.nextSide(moveRuntime);
//			_x=_x+_vx*moveRuntime;
//			_y=_y+_vy*moveRuntime;
			x_off=_vx*moveRuntime;
			y_off=_vy*moveRuntime;
		 	confChk.checkConflict(x_off,y_off);
		    
		}

		public  void moveDown(){
		 
		    if(_brake_up){
				if(down_speed<=int0){
					_speed=int0;
					_down=false;
					_brake_up=false;
					_up=true;
				}else{
					_speed=brake(down_speed);
				}
			}
			else if(_brake){
			    if(down_speed<=int0){
					_speed=int0;
				}else{
					_speed=brake(down_speed);
				}
			}else
		    if(_relaseAccelerator){
				
				if(down_speed<=int0){
					_down=false;
					_speed=int0;
				}else{
					_speed=relaseAccelerator(down_speed);
				}
			}else
			if(_down){
				if(down_speed<carInfo.maxDownSpeed){
					_speed=go(down_speed);
				}else{
					_speed=down_speed;
				}
			}
			sideClipContrl.nextSide(moveRuntime);
//			_x=_x+_vx*moveRuntime;
//			_y=_y+_vy*moveRuntime;
			x_off=_vx*moveRuntime;
			y_off=_vy*moveRuntime;
		 	confChk.checkConflict(x_off,y_off);
		}
		public void moveBySideClip(){
			sideClipContrl.nextSide(moveRuntime);
//			_x=_x+_vx*moveRuntime;
//			_y=_y+_vy*moveRuntime;
			x_off=_vx*moveRuntime;
			y_off=_vy*moveRuntime;
		 	confChk.checkConflict(x_off,y_off);
		}
		


        public void clearSideclip(){
        	sideClipContrl.hasSideClip=false;
        	sideClipContrl.speed=int0;
        }
        public boolean onJump=false;
        public boolean crashEnable(){
        	if(dead)return false;
        	if(ready==0)return false;
        	if(onJump)return false;
        	return true;
        }
		public ArrayList getSkills() {
			return skills;
		}
		public void setSkills(ArrayList skills) {
			this.skills = skills;
		}
}
